﻿using System;
using System.Globalization;
using System.Xml.Linq;
using IcicleFramework.Entities;
using Microsoft.Xna.Framework;

namespace IcicleFramework.Components.Actions
{
    public class TimedAction : BaseAction, ITimedAction
    {
        public float IdleTime { get; set; }

        public float ChargeTime { get; set; }

        public float IdleTimeRemaining { get; protected set; }

        public float ChargeTimeRemaining { get; protected set; }

        public TimedAction()
        {
            IdleTime = 0f;
            ChargeTime = 0f;
        }

        public TimedAction(TimedAction old)
            :base(old)
        {
            this.IdleTime = old.IdleTime;
            this.ChargeTime = old.ChargeTime;
        }

        public override void Update(GameTime gameTime)
        {
            if (!PerformingActions)
                return;

            if (State == ActionState.Idle)
            {
                if (IdleTimeRemaining > 0f)
                {
                    IdleTimeRemaining -= (float)gameTime.ElapsedGameTime.TotalSeconds;
                }
                else
                {
                    ChangeState(gameTime);
                }
            }
            else if (State == ActionState.Charging)
            {
                if (ChargeTimeRemaining > 0f)
                {
                    ChargeTimeRemaining -= (float)gameTime.ElapsedGameTime.TotalSeconds;
                }
                else
                {
                    ChangeState(gameTime);
                }
            }
            else if (State == ActionState.PerfomingAction)
            {
                ChangeState(gameTime);
            }
        }

        protected override void ChangeState(GameTime gameTime)
        {
            base.ChangeState(gameTime);

            IdleTimeRemaining = State == ActionState.Idle ? IdleTime : 0f;
            ChargeTimeRemaining = State == ActionState.Charging ? ChargeTime : 0f;
        }

        protected virtual void PrepareForExecution()
        {
            IdleTimeRemaining = IdleTime;
            ChargeTimeRemaining = ChargeTime;
        }

        public override void Execute(IGameObject target, IActionData data = null, bool continuous = false)
        {
            PrepareForExecution();

            base.Execute(target, data, continuous);
        }

        public override IAction DeepClone()
        {
            return new TimedAction(this);
        }

        public override void Deserialize(XElement element)
        {
            var currElem = element.Element("idleTime");
            float idleTime = 0f, chargeTime = 0f;

            if (currElem != null)
            {
                float.TryParse(currElem.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out idleTime);
            }
            IdleTime = idleTime;

            currElem = element.Element("chargeTime");
            if (currElem != null)
            {
                float.TryParse(currElem.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out chargeTime);
            }
            ChargeTime = chargeTime;

            base.Deserialize(element);
        }
    }
}
